﻿// * Write a program that exchanges bits {p, p+1, …, p+k-1) with 
// bits {q, q+1, …, q+k-1} of given 32-bit unsigned integer.


using System;

class ExchangeKBits
{
    static uint GetBit(uint number, int position)
    {
        uint mask = 1U << position;

        return ((mask & number) >> position);
    }

    static uint SetBit(uint number, uint bitState, int bitPosition)
    {
        if (bitState == 0)
        {
            uint maskClear = ~(1U << bitPosition);

            number &= maskClear;
        }
        if (bitState == 1)
        {
            uint maskSet = 1U << bitPosition;

            number |= maskSet;
        }
        return number;
    }

    static void Main()
    {
        Console.Write("Enter the integer:");
        uint number = uint.Parse(Console.ReadLine());

        Console.Write("Enter P (0-31):");
        int startP = int.Parse(Console.ReadLine());

        Console.Write("Enter Q (0-31):");
        int startQ = int.Parse(Console.ReadLine());

        if (((startP < 0) || (startP > 31)) || ((startQ < 0) || (startQ > 31)))
        {
            Console.WriteLine("Invalid bit positions. Try again.");
        }
        else
        {
            int maxBits = 32 - ((startP > startQ) ? startP : startQ);
            Console.Write("Enter K (max {0} bits):", maxBits);

            int numberOfBits = int.Parse(Console.ReadLine());

            if ((numberOfBits < 1) || (numberOfBits > maxBits))
            {
                Console.WriteLine("Invalid number of bits");

                return;
            }

            for (int i = 0; i <= numberOfBits - 1; i++)
            {
                //save the two bits in a variables
                uint bitStateOne = GetBit(number, startP + i);

                uint bitStateTwo = GetBit(number, startQ + i);

                //set the bits exchanging their positions
                number = SetBit(number, bitStateOne, startQ + i);

                number = SetBit(number, bitStateTwo, startP + i);
            }

            Console.WriteLine("The new number is: {0}", number);
        }
    }
}
